﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Security;

namespace RCMC
{
	/// <summary>
	/// Based on http://www.emilstefanov.net/Projects/VistaGlass.aspx
	/// </summary>
	internal class GlassWindow
	{
		[StructLayout(LayoutKind.Sequential)]
		private struct DWM_BLURBEHIND
		{
			public DwmBlurBehindFlags dwFlags;
			public bool fEnable;
			public IntPtr hRgnBlur;
			public bool fTransitionOnMaximized;
		}

		[SecurityCritical, SuppressUnmanagedCodeSecurity, DllImport("dwmapi.dll")]
		public static extern int DwmIsCompositionEnabled(out int enabled);

		[DllImport("dwmapi.dll")]
		private static extern IntPtr DwmEnableBlurBehindWindow(IntPtr hWnd, ref DWM_BLURBEHIND pBlurBehind);
		[DllImport("DwmApi.dll")]
		private static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset);

		private static bool SupportAero()
		{
			if (Environment.OSVersion.Version.Major >= 6)
			{
				try
				{
					int enabled;

					DwmIsCompositionEnabled(out enabled);

					return enabled != 0;
				}
				catch
				{
				}
			}

			return false;
		}

		public static bool Glass(Window window)
		{
			if (SupportAero())
			{
				try
				{
					window.Background = Brushes.Transparent;

					WindowInteropHelper windowInteropHelper = new WindowInteropHelper(window);
					IntPtr myHwnd = windowInteropHelper.Handle;
					HwndSource mainWindowSrc = System.Windows.Interop.HwndSource.FromHwnd(myHwnd);

					mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

					DWM_BLURBEHIND blurBehindParameters = new DWM_BLURBEHIND();
					blurBehindParameters.dwFlags = DwmBlurBehindFlags.DWM_BB_ENABLE;
					blurBehindParameters.fEnable = true;
					blurBehindParameters.hRgnBlur = IntPtr.Zero;

					DwmEnableBlurBehindWindow(myHwnd, ref blurBehindParameters);

					return true;
				}
				catch 
				{ 
				}
			}

			return false;
		}

		public static bool ExtendedGlass(Window window)
		{
			if (SupportAero())
			{
				try
				{
					window.Background = Brushes.Transparent;

					WindowInteropHelper windowInteropHelper = new WindowInteropHelper(window);
					IntPtr myHwnd = windowInteropHelper.Handle;
					HwndSource mainWindowSrc = System.Windows.Interop.HwndSource.FromHwnd(myHwnd);

					mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

					MARGINS margins = new MARGINS()
					{
						cxLeftWidth = -1,
						cxRightWidth = -1,
						cyBottomHeight = -1,
						cyTopHeight = -1
					};

					DwmExtendFrameIntoClientArea(myHwnd, ref margins);

					return true;
				}
				catch
				{
				}
			}

			return false;
		}

		public static bool ExtendedGlassWithoutBorder(Window window)
		{
			if (SupportAero())
			{
				try
				{
					window.AllowsTransparency = true;
					window.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
					window.ResizeMode = ResizeMode.NoResize;
					window.WindowStyle = WindowStyle.None;

					WindowInteropHelper windowInteropHelper = new WindowInteropHelper(window);
					IntPtr myHwnd = windowInteropHelper.Handle;
					HwndSource mainWindowSrc = System.Windows.Interop.HwndSource.FromHwnd(myHwnd);

					mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

					DWM_BLURBEHIND blurBehindParameters = new DWM_BLURBEHIND();
					blurBehindParameters.dwFlags = DwmBlurBehindFlags.DWM_BB_ENABLE;
					blurBehindParameters.fEnable = true;
					blurBehindParameters.hRgnBlur = IntPtr.Zero;

					DwmEnableBlurBehindWindow(myHwnd, ref blurBehindParameters);

					return true;
				}
				catch
				{
				}
			}

			return false;
		}


	}

	[Flags]
	internal enum DwmBlurBehindFlags : uint
	{
		/// <summary>
		/// Indicates a value for fEnable has been specified.
		/// </summary>
		DWM_BB_ENABLE = 0x00000001,

		/// <summary>
		/// Indicates a value for hRgnBlur has been specified.
		/// </summary>
		DWM_BB_BLURREGION = 0x00000002,

		/// <summary>
		/// Indicates a value for fTransitionOnMaximized has been specified.
		/// </summary>
		DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004
	}

	[StructLayout(LayoutKind.Sequential)]
	internal struct MARGINS
	{
		public int cxLeftWidth;      // width of left border that retains its size
		public int cxRightWidth;     // width of right border that retains its size
		public int cyTopHeight;      // height of top border that retains its size
		public int cyBottomHeight;   // height of bottom border that retains its size
	}
}
